package cn.cnlee.arch.http;


import android.content.Context;

import com.franmontiel.persistentcookiejar.ClearableCookieJar;
import com.franmontiel.persistentcookiejar.PersistentCookieJar;
import com.franmontiel.persistentcookiejar.cache.SetCookieCache;
import com.franmontiel.persistentcookiejar.persistence.SharedPrefsCookiePersistor;

import java.io.File;
import java.util.concurrent.TimeUnit;

import okhttp3.Cache;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

import static cn.cnlee.arch.util.ClassUtil.checkNotNull;


/**
 * 远程请求客户端
 */
public class RemoteClient {

    private static volatile RemoteClient mRemoteClient = null;
    private static Retrofit mRetrofit;
    private static OkHttpClient.Builder mBuilder;
    private static String BASE_URL;
    private static OkHttpClient mOkHttpClient;

    private RemoteClient() {
    }

    public static RemoteClient getInstance() {
        if (mRemoteClient == null) {
            synchronized (RemoteClient.class) {
                if (mRemoteClient == null) {
                    mRemoteClient = new RemoteClient();
                }
            }
        }
        return mRemoteClient;
    }

    public static class Builder {
        private OkHttpClient mOkHttpClient;
        private OkHttpClient.Builder mBuilder;
        private Retrofit mRetrofit;
        private Context mContext;

        public Builder(Context context) {
            this.mContext = context;
        }

        /**
         * 初始化OKHttpClient,设置缓存,设置超时时间,设置打印日志
         * @return Builder
         */
        public Builder initOkHttp() {
            HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
            interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
            if (mBuilder == null) {
                synchronized (RemoteClient.class) {
                    if (mBuilder == null) {
                        Cache cache = new Cache(new File(mContext.getCacheDir(), "HttpCache"), 1024 * 1024 * 10);
                        ClearableCookieJar cookieJar = new PersistentCookieJar(new SetCookieCache(), new SharedPrefsCookiePersistor(mContext));
                        mBuilder = new OkHttpClient.Builder()
                                .cache(cache)
                                .addInterceptor(interceptor)
                                .connectTimeout(30, TimeUnit.SECONDS)
                                .writeTimeout(30, TimeUnit.SECONDS)
                                .readTimeout(30, TimeUnit.SECONDS)
                                .cookieJar(cookieJar)
                        ;
                    }
                }
            }
            return this;
        }

        /**
         * 添加拦截器
         * @param mInterceptor
         * @return Builder
         */
        public Builder addInterceptor(Interceptor mInterceptor) {
            checkNotNull(mInterceptor);
            this.mBuilder.addInterceptor(mInterceptor);
            return this;
        }

        /**
         * 创建retrofit
         * @param baseUrl
         * @return Builder
         */
        public Builder createRetrofit(String baseUrl) {
            checkNotNull(baseUrl);
            Retrofit.Builder builder = new Retrofit.Builder()
                    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                    .addConverterFactory(GsonConverterFactory.create())
                    .baseUrl(baseUrl);
            BASE_URL = baseUrl;
            this.mOkHttpClient = mBuilder.build();
            this.mRetrofit = builder.client(mOkHttpClient)
                    .build();
            return this;
        }

        public void build() {
            RemoteClient.getInstance().build(this);
        }

    }

    private void build(Builder builder) {
        checkNotNull(builder);
        checkNotNull(builder.mBuilder);
        checkNotNull(builder.mOkHttpClient);
        checkNotNull(builder.mRetrofit);
        mBuilder = builder.mBuilder;
        mOkHttpClient = builder.mOkHttpClient;
        mRetrofit = builder.mRetrofit;
    }

    /**
     * 构建Service接口服务
     * @param clz 接口class
     * @param <T>
     * @return
     */
    public <T> T create(Class<T> clz) {
        checkNotNull(clz);
        checkNotNull(mRetrofit);
        return mRetrofit.create(clz);
    }

}
